export class ProxyManager {
  constructor() {
    this.tabProxies = new Map(); // tabId -> proxyConfig 映射
  }

  async setProxyForTab(tabId, proxyConfig) {
    if (!proxyConfig || !proxyConfig.enabled) {
      await this.clearProxyForTab(tabId);
      return;
    }

    this.tabProxies.set(tabId, proxyConfig);

    const proxySettings = this.buildProxySettings(proxyConfig);
    
    // 设置代理规则
    await chrome.proxy.settings.set({
      value: proxySettings,
      scope: 'regular'
    });

    console.log(`Proxy set for tab ${tabId}:`, proxyConfig);
  }

  async clearProxyForTab(tabId) {
    this.tabProxies.delete(tabId);
    
    // 如果没有其他标签页使用代理，清除代理设置
    if (this.tabProxies.size === 0) {
      await chrome.proxy.settings.clear({
        scope: 'regular'
      });
    }
  }

  buildProxySettings(proxyConfig) {
    const { type, host, port, username, password } = proxyConfig;

    let proxySettings = {
      mode: 'fixed_servers',
      rules: {}
    };

    const proxyServer = {
      scheme: type.toLowerCase(), // http, https, socks4, socks5
      host: host,
      port: parseInt(port)
    };

    switch (type.toLowerCase()) {
      case 'http':
      case 'https':
        proxySettings.rules.singleProxy = proxyServer;
        break;
      case 'socks4':
      case 'socks5':
        proxySettings.rules.singleProxy = {
          ...proxyServer,
          scheme: type.toLowerCase()
        };
        break;
      default:
        throw new Error(`Unsupported proxy type: ${type}`);
    }

    return proxySettings;
  }

  async testProxy(proxyConfig) {
    try {
      const testUrl = 'https://httpbin.org/ip';
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 10000); // 10秒超时

      // 临时设置代理进行测试
      const originalSettings = await chrome.proxy.settings.get({});
      await chrome.proxy.settings.set({
        value: this.buildProxySettings(proxyConfig),
        scope: 'regular'
      });

      const response = await fetch(testUrl, {
        signal: controller.signal
      });

      clearTimeout(timeoutId);
      
      // 恢复原始代理设置
      await chrome.proxy.settings.set({
        value: originalSettings.value,
        scope: 'regular'
      });

      if (response.ok) {
        const result = await response.json();
        return {
          success: true,
          ip: result.origin,
          latency: Date.now() - startTime
        };
      } else {
        throw new Error(`HTTP ${response.status}`);
      }
    } catch (error) {
      return {
        success: false,
        error: error.message
      };
    }
  }

  getProxyForTab(tabId) {
    return this.tabProxies.get(tabId);
  }

  getAllActiveProxies() {
    return Array.from(this.tabProxies.entries());
  }

  async handleProxyAuth(details) {
    const tabId = details.tabId;
    const proxyConfig = this.tabProxies.get(tabId);
    
    if (proxyConfig && proxyConfig.username && proxyConfig.password) {
      return {
        authCredentials: {
          username: proxyConfig.username,
          password: proxyConfig.password
        }
      };
    }
    
    return {};
  }

  // 设置代理认证监听器
  setupProxyAuth() {
    chrome.webRequest.onAuthRequired.addListener(
      this.handleProxyAuth.bind(this),
      { urls: ['<all_urls>'] },
      ['blocking']
    );
  }

  // 移除代理认证监听器
  removeProxyAuth() {
    chrome.webRequest.onAuthRequired.removeListener(this.handleProxyAuth);
  }

  // 获取代理统计信息
  getProxyStats() {
    const stats = {
      totalProxies: this.tabProxies.size,
      proxyTypes: {},
      activeTabs: Array.from(this.tabProxies.keys())
    };

    for (const [tabId, config] of this.tabProxies) {
      const type = config.type.toLowerCase();
      stats.proxyTypes[type] = (stats.proxyTypes[type] || 0) + 1;
    }

    return stats;
  }

  // 批量设置代理
  async setBatchProxies(tabProxyMappings) {
    const promises = tabProxyMappings.map(({ tabId, proxyConfig }) => 
      this.setProxyForTab(tabId, proxyConfig)
    );
    
    await Promise.all(promises);
  }

  // 清除所有代理设置
  async clearAllProxies() {
    this.tabProxies.clear();
    await chrome.proxy.settings.clear({
      scope: 'regular'
    });
  }
} 